home *** CD-ROM | disk | FTP | other *** search
/ CD Ware Multimedia 1995 May / cd Ware (Juegos) Epimundo.iso / DOS / PRGMMING / M2PROTOS.ZIP / PATHFIND.MOD < prev    next >
Encoding:
Modula Implementation  |  1991-02-09  |  5.5 KB  |  211 lines

  1. (*%F _fdata *)
  2. (*# call(seg_name => null) *)
  3. (*%E *)
  4. (*# module(implementation=>off) *)
  5. (*# data(seg_name => null) *)
  6. (*# call(o_a_copy => off) *)
  7. (*# check(stack=>off,
  8.           index=>off,
  9.           range=>off,
  10.           overflow=>off,
  11.           nil_ptr=>off) *)
  12. IMPLEMENTATION MODULE PathFind;
  13.  
  14. (* Source code for JPI TopSpeed Modula-2 by
  15.  
  16.     Carl Neiburger
  17.     169 N. 25th St.
  18.     San Jose, Calif. 95116
  19.  
  20.     CompuServe No. 72336,2257
  21.  
  22. NOTE: This module requires MODULE FioAsm by the same author.  If you can't 
  23. find this module, you can write your own routines for this procedure:
  24.  
  25. PROCEDURE Drives(): SHORTCARD;
  26.     (* tells how many on system *)
  27.  
  28.     NFIO is a substitute for JPI's FIO, and all the imported procedures 
  29.        listed here work the same as in FIO
  30. *)
  31.  
  32. FROM Lib IMPORT Environment, CommandType;
  33. FROM Str IMPORT Append, Caps, CHARSET, Copy, Delete, Item, Length, Pos,
  34.          Slice, Concat, Compare;
  35. FROM NFIO IMPORT GetDir, ChDir, OK, Exists;
  36. FROM FioAsm IMPORT Drives, ReadFirstEntry, ReadNextEntry, 
  37.          FileAttributes, DirEntry, FileAttr;
  38. FROM Storage IMPORT ALLOCATE, DEALLOCATE;
  39.  
  40. CONST
  41.     FileOrDir = FileAttr{readonly,directory};
  42.  
  43. TYPE str80 = ARRAY [0..79] OF CHAR;
  44.  
  45. PROCEDURE FindEnvStr( target : ARRAY OF CHAR; VAR string: ARRAY OF CHAR );
  46. VAR i : CARDINAL; c : CommandType;
  47. BEGIN
  48.     i := 0;
  49.     REPEAT
  50.          c := Environment(i);
  51.          Copy(string, c^ );
  52.          Caps(string);
  53.          INC(i)
  54.     UNTIL ( string[0] = 0C ) OR ( Pos(string, target ) < MAX( CARDINAL ) );
  55.     i := Pos(string, '=');
  56.     IF i < MAX ( CARDINAL ) THEN
  57.          Delete(string, 0, i+1);
  58.          WHILE string[0] IN CHARSET{11C, 40C} DO 
  59.               Delete(string, 0, 1) 
  60.          END
  61.     END
  62. END FindEnvStr;
  63.  
  64. PROCEDURE FindPath(PathName,
  65.                    TargetName: ARRAY OF CHAR;
  66.                VAR TargetPath: ARRAY OF CHAR): BOOLEAN;
  67.  
  68. VAR path: str80; item: PathStr;  i : CARDINAL;
  69. BEGIN
  70.     IF Exists( TargetName ) THEN
  71.          Copy(TargetPath, TargetName);
  72.          RETURN TRUE
  73.     END;
  74.     FindEnvStr( PathName, path );
  75.     i := 0;
  76.     LOOP
  77.          Item( item, path, CHARSET{';'}, i);
  78.          IF item[0] = 0C THEN
  79.               Copy(TargetPath, TargetName);
  80.               RETURN FALSE
  81.          END;
  82.          IF NOT ( item[Length(item)-1] IN CHARSET{':', '\'} ) THEN
  83.               Append( item, '\' );
  84.          END;
  85.          Append( item, TargetName );
  86.          IF Exists( item ) THEN
  87.               Copy(TargetPath, item);
  88.               RETURN TRUE;
  89.          END;
  90.          INC ( i )
  91.     END;
  92. END FindPath;
  93.  
  94. PROCEDURE ParsePath(VAR Path: PathStr; 
  95.                     VAR FileName: PathTail): BOOLEAN;
  96. VAR DE: DirEntry;
  97.     Len: CARDINAL;
  98.     Parent,
  99.     PathOnly : BOOLEAN;
  100.     CurrentPath : PathStr;
  101.  
  102. PROCEDURE CompletePath(): BOOLEAN;
  103. VAR SavePath: PathStr; d : SHORTCARD;
  104. BEGIN
  105.     IF Path[1] = ':' THEN 
  106.          d := SHORTCARD(CAP(Path[0])) - 64;
  107.          IF d > Drives() THEN
  108.               RETURN FALSE
  109.          END
  110.     ELSE
  111.          d := 0
  112.     END;
  113.     GetDir(0, SavePath);
  114.     IF Path[0] = 0C THEN
  115.          Path := SavePath;
  116.          RETURN TRUE
  117.     END;
  118.     ChDir ( Path );
  119.     IF OK THEN
  120.          GetDir( d, Path );
  121.          ChDir( SavePath );
  122.          RETURN TRUE
  123.     END;
  124.     RETURN FALSE
  125. END CompletePath;
  126.  
  127. PROCEDURE SlicePath;
  128. VAR i: CARDINAL;
  129. BEGIN
  130.     i := Len;
  131.     WHILE NOT (Path[i] IN CHARSET{':', '\'}) AND (i > 0) DO
  132.          DEC(i)
  133.     END;
  134.     IF (i = Len) AND (Path[i] IN CHARSET{':', '\', '.'}) THEN
  135.          PathOnly := TRUE;
  136.          RETURN 
  137.     ELSE
  138.          PathOnly := FALSE
  139.     END;
  140.     IF i = 0 THEN
  141.          Copy(FileName, Path);
  142.          Path[0] := 0C;
  143.          RETURN 
  144.     END;
  145.     Slice(FileName, Path, i+1, Len );
  146.     IF (Path[i] = ':') OR (Path[i-1] = ':') THEN
  147.          INC(i);
  148.     END;
  149.     Path[i] := 0C;
  150. END SlicePath;
  151.  
  152. BEGIN (* ParsePath *)
  153.     Len := Length(Path) - 1;
  154.     Caps(Path);
  155.     Caps(FileName);
  156.     Parent := Compare(Path, '..') = 0;
  157.     IF Parent THEN
  158.          GetDir( 0, CurrentPath );
  159.          Parent := Length(CurrentPath) > 3
  160.     END;
  161.     IF Parent OR ReadFirstEntry( Path, FileOrDir, DE ) THEN
  162.          IF (Pos(Path, '*') < MAX(CARDINAL) )
  163.             OR (Pos(Path, '?') < MAX(CARDINAL) )
  164.             OR NOT ( Parent OR (directory IN DE.attr) ) THEN
  165.               SlicePath;
  166.          END;
  167.          RETURN CompletePath()
  168.     END;
  169.     SlicePath;
  170.     RETURN CompletePath() AND PathOnly (* RETURN FALSE if file not found *)
  171. END ParsePath;
  172.  
  173. PROCEDURE FileTree ( Path: PathStr ): FilePtr;
  174. VAR Ptr, this: FilePtr; p: PathStr; FileName: PathTail; DE: DirEntry;
  175. BEGIN
  176.     FileName := '*.*';
  177.     IF ParsePath( Path, FileName) THEN
  178.          IF Path[Length(Path)-1] <> '\' THEN
  179.               Append( Path, '\')
  180.          END;
  181.          Concat( p, Path, FileName);
  182.          IF ReadFirstEntry( p, FileAttr{readonly}, DE ) THEN
  183.               NEW(this);
  184.               Concat(this^.Name, Path, DE.Name);
  185.               this^.Next := NIL;
  186.               Ptr := this;
  187.               WHILE ReadNextEntry( DE ) DO
  188.                    NEW(this^.Next);
  189.                    this := this^.Next;
  190.                    Concat(this^.Name, Path, DE.Name);
  191.                    this^.Next := NIL
  192.               END;
  193.               RETURN Ptr
  194.          END
  195.     END;
  196.     RETURN NIL;
  197. END FileTree;
  198.  
  199. PROCEDURE UnFileTree ( VAR Ptr : FilePtr );
  200. VAR this: FilePtr;
  201. BEGIN;
  202.     this := Ptr;
  203.     WHILE this <> NIL DO 
  204.          Ptr := Ptr^.Next;
  205.          DISPOSE(this);
  206.          this := Ptr
  207.     END
  208. END UnFileTree;
  209.  
  210. END PathFind.
  211.